package cn.starrysky108.simpleerp.core.handler;


import cn.starrysky108.simpleerp.core.annotation.IgnoreResponseAdvice;
import cn.starrysky108.simpleerp.core.base.BaseResponseEntity;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Objects;

/**
 * @author Carl Lee
 * 统一结果处理器
 */
@Slf4j
@RestControllerAdvice(basePackages = "cn.starrysky108.simpleerp")
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {


    @Override
    public boolean supports(MethodParameter returnType, @Nullable  Class<? extends HttpMessageConverter<?>> converterType) {
        //判断方法和类上是否才存在IgnoreResponseAdvice注解，存在则忽略拦截
        return !returnType.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class) &&
                !Objects.requireNonNull(returnType.getMethod()).isAnnotationPresent(IgnoreResponseAdvice.class);
    }

    @Override
    @Nullable
    public Object beforeBodyWrite( Object body,@Nullable MethodParameter returnType,@Nullable MediaType selectedContentType,
                                   @Nullable Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                   @Nullable ServerHttpRequest httpRequest, @Nullable ServerHttpResponse httpResponse) {
        //具体返回值处理
        //情况1 如果返回的body为null
        if (body == null) {
            return BaseResponseEntity.failure("无响应结果");
        } else {
            //文件上传下载，不需要改动，直接返回
            if (body instanceof Resource) {
                return body;
            }
            //返回的是字符串形式，需要进行特殊处理，否则会又异常
            if (body instanceof String) {
                ObjectMapper objectMapper = new ObjectMapper();
                // 将数据包装在ResultVO里后，再转换为json字符串响应给前端
                try {
                    return objectMapper.writeValueAsString(BaseResponseEntity.success(body));
                } catch (JsonProcessingException e) {
                    log.error(e.getMessage());
                }
            }
            //返回的是非字符串格式，实际上很多时候用都是是在应用程返回的对象居多
            if (body instanceof BaseResponseEntity) {
                //已经在其他层封装成了HttpResultVO,直接返回
                return body;
            }
            //默认统一返回
            return BaseResponseEntity.success(body);


        }
    }
}
